package com.jinzecloud.reportapproval.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.deepoove.poi.config.Configure;
import com.deepoove.poi.data.Pictures;
import com.deepoove.poi.plugin.table.LoopRowTableRenderPolicy;
import com.jinzecloud.reportapproval.bean.KeyInstrumentDetail;
import com.jinzecloud.reportapproval.bean.Report;
import com.jinzecloud.reportapproval.bean.TemperatureHumidity;
import com.jinzecloud.reportapproval.dto.AdminDto;
import com.jinzecloud.reportapproval.dto.AuditParam;
import com.jinzecloud.reportapproval.dto.DataStagingParam;
import com.jinzecloud.reportapproval.enums.AuditRoleEnums;
import com.jinzecloud.reportapproval.enums.StateEnum;
import com.jinzecloud.reportapproval.enums.TableEnums;
import com.jinzecloud.reportapproval.service.KeyInstrumentDetailService;
import com.jinzecloud.reportapproval.utils.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;

import java.io.File;
import java.nio.file.StandardCopyOption;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import com.jinzecloud.reportapproval.mapper.KeyInstrumentMapper;
import com.jinzecloud.reportapproval.bean.KeyInstrument;
import com.jinzecloud.reportapproval.service.KeyInstrumentService;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;


@Service("keyInstrumentService")
public class KeyInstrumentServiceImpl extends ServiceImpl<KeyInstrumentMapper, KeyInstrument> implements KeyInstrumentService {

    @Autowired
    private KeyInstrumentDetailService keyInstrumentDetailService;
    @Autowired
    private HttpServletRequest request;

    @Autowired
    private FileUploadUtil fileUploadUtil;

    private SimpleDateFormat inputFormat = new SimpleDateFormat("yyyy-MM-dd"); // 原始格式


    private SimpleDateFormat sdf = new SimpleDateFormat("yyyy 年 MM 月 dd 日");


    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        QueryWrapper<KeyInstrument> keyInstrumentQueryWrapper = new QueryWrapper<>();
        String key = (String) params.get("key");
        if (key != null) {
            keyInstrumentQueryWrapper.like("project_number", key);
        }
        IPage<KeyInstrument> page = this.page(
                new Query<KeyInstrument>().getPage(params),
                keyInstrumentQueryWrapper
        );

        return new PageUtils(page);
    }

    @Override
    @Transactional
    public R addKeyInstrument(KeyInstrument keyInstrument) {
        if (save(keyInstrument)) {
            List<KeyInstrumentDetail> detailList = keyInstrument.getDetailList();
            if (detailList.size() > 0) {
                for (KeyInstrumentDetail keyInstrumentDetail : detailList) {
                    keyInstrumentDetail.setParentId(keyInstrument.getId());
                    keyInstrumentDetailService.save(keyInstrumentDetail);
                }
            }
        }
        return R.ok();
    }

    @Override
    @Transactional
    public R updateKeyInstrument(KeyInstrument keyInstrument) {
        List<KeyInstrumentDetail> parentId = keyInstrumentDetailService.list(new QueryWrapper<KeyInstrumentDetail>().eq("parent_id", keyInstrument.getId()));
        if (parentId.size() > 0) {
            for (KeyInstrumentDetail keyInstrumentDetail : parentId) {
                keyInstrumentDetailService.removeById(keyInstrumentDetail);
            }
        }
        if (updateById(keyInstrument)) {
            List<KeyInstrumentDetail> detailList = keyInstrument.getDetailList();
            if (detailList.size() > 0) {
                for (KeyInstrumentDetail keyInstrumentDetail : detailList) {
                    keyInstrumentDetail.setParentId(keyInstrument.getId());
                    keyInstrumentDetailService.save(keyInstrumentDetail);
                }
            }
        }
        return R.ok();
    }

    @Override
    public String viewPdf(Integer id) {
        KeyInstrument keyInstrument = getById(id);
        String dataTime = keyInstrument.getDataTime();
        try {
            keyInstrument.setDataTime(sdf.format(inputFormat.parse(dataTime)));
        } catch (ParseException e) {
            throw new RuntimeException(e);
        }
        List<KeyInstrumentDetail> keyInstrumentDetailList = keyInstrumentDetailService.list(new QueryWrapper<KeyInstrumentDetail>().eq("parent_id", id).orderByAsc("id"));

        if (keyInstrumentDetailList.size() < 14) {
            // 计算需要添加多少个元素
            int itemsToAdd = 14 - keyInstrumentDetailList.size();

            // 循环添加空的或默认的 KeyInstrumentDetail 对象
            for (int i = 0; i < itemsToAdd; i++) {
                KeyInstrumentDetail emptyDetail = new KeyInstrumentDetail();
                emptyDetail.setId(i);
                emptyDetail.setInstrumentName("");
                emptyDetail.setKeyInstrument("");
                emptyDetail.setInstrumentNumber("");
                emptyDetail.setIndate("");
                emptyDetail.setValueTa("");
                // 如果需要，可以给 emptyDetail 设置默认值
                keyInstrumentDetailList.add(emptyDetail);
            }
        }
        keyInstrument.setDetailList(keyInstrumentDetailList);

        LoopRowTableRenderPolicy policy = new LoopRowTableRenderPolicy();
        JSONObject data = JSONObject.parseObject(JSONObject.toJSONString(keyInstrument));

        if (StrUtil.isNotEmpty(data.getString("inspector"))) data.put("inspector", Pictures.ofUrl(data.getString("inspector")).size(30, 10).create());
        if (StrUtil.isNotEmpty(data.getString("notekeeper"))) data.put("notekeeper", Pictures.ofUrl(data.getString("notekeeper")).size(30, 10).create());
        if (StrUtil.isNotEmpty(data.getString("checker"))) data.put("checker", Pictures.ofUrl(data.getString("checker")).size(30, 10).create());



        //word
        File tempFile = WordUtil.getWordFile("template/instrument.docx", data, Configure.builder().bind("detailList", policy));

        if (tempFile == null) return null;
        String fileName = "主要仪器设备记录表";
        String uploadDirectory = fileUploadUtil.getUploadFilePath("temp");
        String filePath = uploadDirectory + keyInstrument.getProjectNumber() + fileName;
        String savePath = RequestUtils.getBasePath(request) + "upload/temp/" + keyInstrument.getProjectNumber() +fileName;
        FileUtil.copyFile(tempFile, new File(filePath + ".docx"), StandardCopyOption.REPLACE_EXISTING);
        PDFUtil.WordToPdf(tempFile, new File(filePath + ".pdf"));

        update(new LambdaUpdateWrapper<KeyInstrument>().set(KeyInstrument::getWordPath, savePath + ".docx").set(KeyInstrument::getPdfPath, savePath + ".pdf").eq(KeyInstrument::getId, id));

        return RequestUtils.getBasePath(request) + "upload/temp/" + keyInstrument.getProjectNumber() + fileName + ".pdf";
    }

    @Override
    public Object auditList(DataStagingParam param) {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        LambdaQueryWrapper<KeyInstrument> queryWrapper = new LambdaQueryWrapper<>();
        List<AdminDto> adminDto = AuditUtil.getAdminDto(authentication.getName());
        Set<Integer> roleSet = adminDto.stream().map(a -> StateEnum.getStateEnumByAuditRole(a.getRoleCode()).getState()).collect(Collectors.toSet());
        roleSet.remove(StateEnum.UN_SUBMIT.getState());
        queryWrapper.in(KeyInstrument::getStatus, roleSet);
        return page(new Page<>(param.getPageNo(), param.getPageSize()), queryWrapper);
    }

    @Override
    public R audit(AuditParam auditParam) {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        List<AdminDto> adminDos = AuditUtil.getAdminDto(authentication.getName());
        if (CollectionUtil.isEmpty(adminDos)) return R.error("您没有审核权限！");
        KeyInstrument temperatureHumidity = this.getById(auditParam.getId());
        int state = temperatureHumidity.getStatus();
        if (!auditParam.isState()) {
            updateById(temperatureHumidity.setStatus(StateEnum.APPROVAL_NOT_PASS.getState())
                    .setAuditOpinion(auditParam.getAuditOpinion())
                    .setAuditDate(DateUtil.date().toDateStr()));
            return R.ok();
        }
        StateEnum currentAuditState = AuditUtil.getStateText(TableEnums.TEMPERATURE_HUMIDITY.getTableName(), state);
        Integer nextAuditStateIndex = AuditUtil.getNextAuditState(TableEnums.TEMPERATURE_HUMIDITY.getTableName(), state, adminDos.stream().map(AdminDto::getRoleCode).toList());
        AdminDto adminDto = adminDos.stream().filter(a -> StrUtil.equals(a.getRoleCode(), currentAuditState.getAuditRole()))
                .findFirst().orElse(null);
        if (adminDto == null || nextAuditStateIndex == null) return R.error("您没有审核权限！");
        if (StrUtil.equals(adminDto.getRoleCode(), AuditRoleEnums.CHECKER_PERSON.getCode())) temperatureHumidity.setInspector(adminDto.getAdSignature());
        if (StrUtil.equals(adminDto.getRoleCode(), AuditRoleEnums.RECORDER.getCode())) temperatureHumidity.setNotekeeper(adminDto.getAdSignature());
        if (StrUtil.equals(adminDto.getRoleCode(), AuditRoleEnums.CHECKER.getCode())) temperatureHumidity.setChecker(adminDto.getAdSignature());
        temperatureHumidity.setStatus(nextAuditStateIndex)
                .setAuditOpinion(auditParam.getAuditOpinion())
                .setAuditDate(DateUtil.date().toDateStr());
        updateById(temperatureHumidity);
        return R.ok();
    }

    @Override
    public JSONObject KeyInstrumentJson(String projectUuid) {
        KeyInstrument keyInstrument = getOne(new QueryWrapper<KeyInstrument>().eq("project_number",projectUuid));
        if(keyInstrument == null) return null;
        String dataTime = keyInstrument.getDataTime();
        try {
            keyInstrument.setDataTime(sdf.format(inputFormat.parse(dataTime)));
        } catch (ParseException e) {
            throw new RuntimeException(e);
        }
        List<KeyInstrumentDetail> keyInstrumentDetailList = keyInstrumentDetailService.list(new QueryWrapper<KeyInstrumentDetail>().eq("parent_id", keyInstrument.getId()).orderByAsc("id"));
        // 判断列表的大小是否小于 16
        if (keyInstrumentDetailList.size() < 16) {
            // 计算需要添加多少个元素
            int itemsToAdd = 16 - keyInstrumentDetailList.size();

            // 循环添加空的或默认的 KeyInstrumentDetail 对象
            for (int i = 0; i < itemsToAdd; i++) {
                KeyInstrumentDetail emptyDetail = new KeyInstrumentDetail();
                emptyDetail.setId(i);
                emptyDetail.setInstrumentName("");
                emptyDetail.setKeyInstrument("");
                emptyDetail.setInstrumentNumber("");
                emptyDetail.setIndate("");
                emptyDetail.setValueTa("");
                // 如果需要，可以给 emptyDetail 设置默认值
                keyInstrumentDetailList.add(emptyDetail);
            }
        }
        keyInstrument.setDetailList(keyInstrumentDetailList);

        JSONObject data = JSONObject.parseObject(JSONObject.toJSONString(keyInstrument));

        return data;
    }

    @Override
    public String getInfo(String projectNumber) {
        KeyInstrument keyInstrument = getOne(new QueryWrapper<KeyInstrument>().eq("project_number",projectNumber));
        StringBuffer stringBuffer = new StringBuffer();
        if (keyInstrument != null){
            List<KeyInstrumentDetail> list = keyInstrumentDetailService.list(new QueryWrapper<KeyInstrumentDetail>().eq("parent_id", keyInstrument.getId()).orderByAsc("id"));
            for (KeyInstrumentDetail keyInstrumentDetail : list) {
                stringBuffer.append(keyInstrumentDetail.getInstrumentName() + '、');
            }
            return stringBuffer.toString();
        }
        return null;
    }

    @Override
    public String viewWord(Integer id) {
        KeyInstrument keyInstrument = getById(id);
        String dataTime = keyInstrument.getDataTime();
        try {
            keyInstrument.setDataTime(sdf.format(inputFormat.parse(dataTime)));
        } catch (ParseException e) {
            throw new RuntimeException(e);
        }
        List<KeyInstrumentDetail> keyInstrumentDetailList = keyInstrumentDetailService.list(new QueryWrapper<KeyInstrumentDetail>().eq("parent_id", id).orderByAsc("id"));

        if (keyInstrumentDetailList.size() < 14) {
            // 计算需要添加多少个元素
            int itemsToAdd = 14 - keyInstrumentDetailList.size();

            // 循环添加空的或默认的 KeyInstrumentDetail 对象
            for (int i = 0; i < itemsToAdd; i++) {
                KeyInstrumentDetail emptyDetail = new KeyInstrumentDetail();
                emptyDetail.setId(i);
                emptyDetail.setInstrumentName("");
                emptyDetail.setKeyInstrument("");
                emptyDetail.setInstrumentNumber("");
                emptyDetail.setIndate("");
                emptyDetail.setValueTa("");
                // 如果需要，可以给 emptyDetail 设置默认值
                keyInstrumentDetailList.add(emptyDetail);
            }
        }
        keyInstrument.setDetailList(keyInstrumentDetailList);

        LoopRowTableRenderPolicy policy = new LoopRowTableRenderPolicy();
        JSONObject data = JSONObject.parseObject(JSONObject.toJSONString(keyInstrument));

        if (StrUtil.isNotEmpty(data.getString("inspector"))) data.put("inspector", Pictures.ofUrl(data.getString("inspector")).size(30, 10).create());
        if (StrUtil.isNotEmpty(data.getString("notekeeper"))) data.put("notekeeper", Pictures.ofUrl(data.getString("notekeeper")).size(30, 10).create());
        if (StrUtil.isNotEmpty(data.getString("checker"))) data.put("checker", Pictures.ofUrl(data.getString("checker")).size(30, 10).create());



        //word
        File tempFile = WordUtil.getWordFile("template/instrument.docx", data, Configure.builder().bind("detailList", policy));

        if (tempFile == null) return null;
        String fileName = "主要仪器设备记录表";
        String uploadDirectory = fileUploadUtil.getUploadFilePath("temp");
        String filePath = uploadDirectory + keyInstrument.getProjectNumber() + fileName;
        String savePath = RequestUtils.getBasePath(request) + "upload/temp/" + keyInstrument.getProjectNumber() +fileName;
        FileUtil.copyFile(tempFile, new File(filePath + ".docx"), StandardCopyOption.REPLACE_EXISTING);
        PDFUtil.WordToPdf(tempFile, new File(filePath + ".pdf"));

        update(new LambdaUpdateWrapper<KeyInstrument>().set(KeyInstrument::getWordPath, savePath + ".docx").set(KeyInstrument::getPdfPath, savePath + ".pdf").eq(KeyInstrument::getId, id));

        return RequestUtils.getBasePath(request) + "upload/temp/" + keyInstrument.getProjectNumber() + fileName + ".docx";
    }

}
